package net.dgg.dggcloud.core;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;

import java.util.Iterator;
import java.util.Map;

/**
 * dggcloud上下文
 *
 * @author 徐哲
 * @create 2017-10-30 16:03
 */
public class DggApplicationContext implements ApplicationContextAware {
	static Logger logger = LoggerFactory.getLogger(DggApplicationContext.class);
	public static ApplicationContext context = null;

	public static ApplicationContext getSpringContext() {
		return context;
	}

	public void setApplicationContext(ApplicationContext context) throws BeansException {
		DggApplicationContext.context = context;
	}

	public static Object getBean(String beanId) {
		return context.getBean(beanId);
	}

	public static <T> T getBean(String beanId, Class<T> beanClass) {
		return context.getBean(beanId, beanClass);
	}

	public static <T> T getBean(Class<T> beanClass) {
		return context.getBean(beanClass);
	}

	/**
	 * @param className   注册class 全称
	 * @param serviceName 注册别名
	 * @param propertyMap 注入属性
	 */
	public static void addBean(String className, String serviceName, Map propertyMap) {
		try {
			Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
			BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
			if (propertyMap != null) {
				Iterator<?> entries = propertyMap.entrySet().iterator();
				Map.Entry<?, ?> entry;
				while (entries.hasNext()) {
					entry = (Map.Entry<?, ?>) entries.next();
					String key = (String) entry.getKey();
					Object val = entry.getValue();
					beanDefinitionBuilder.addPropertyValue(key, val);

				}
			}
			registerBean(serviceName, beanDefinitionBuilder.getRawBeanDefinition(), context);
		} catch (ClassNotFoundException e) {
			logger.error(className + ",主动注册失败.", e);
		}
	}

	/**
	 * @param className     注册class 全称
	 * @param serviceName   注册别名
	 * @param propertyMap   注入属性
	 * @param initMethod    初始化方法
	 * @param destroyMethod 销毁方法
	 */
	public static void addBean(String className, String serviceName, Map propertyMap, String initMethod, String destroyMethod) {
		try {
			Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
			BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
			if (propertyMap != null) {
				Iterator<?> entries = propertyMap.entrySet().iterator();
				Map.Entry<?, ?> entry;
				while (entries.hasNext()) {
					entry = (Map.Entry<?, ?>) entries.next();
					String key = (String) entry.getKey();
					Object val = entry.getValue();
					beanDefinitionBuilder.setInitMethodName(initMethod);
					beanDefinitionBuilder.setDestroyMethodName(destroyMethod);

					beanDefinitionBuilder.addPropertyValue(key, val);

				}
			}
			registerBean(serviceName, beanDefinitionBuilder.getRawBeanDefinition(), context);
		} catch (ClassNotFoundException e) {
			logger.error(className + ",主动注册失败.", e);
		}
	}

	/**
	 * @param beanName
	 * @param beanDefinition
	 * @desc 向spring容器注册bean
	 */
	public static void registerBean(String beanName, BeanDefinition beanDefinition, ApplicationContext context) {
		ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) context;
		BeanDefinitionRegistry beanDefinitonRegistry = (BeanDefinitionRegistry) configurableApplicationContext
				.getBeanFactory();
		beanDefinitonRegistry.registerBeanDefinition(beanName, beanDefinition);
	}

}
